import Node from '../core/Node';

export default class Polygon extends Node {
  static TYPE = {
    STROKE: 1,
    FILL: 2,
  }
  static GRADIENTDIRECT = {
    VERTICAL: 'vertical',
    HORIZONTAL: 'horizontal',
    DIAGONAL: 'diagonal',
    RADIAL: 'radial',
  }

  constructor(canvas, style, points = []) {
    super(canvas, style);
    this.type = style.type || Polygon.TYPE.STROKE;
    this.gradientDirect = style.gradientDirect || Polygon.GRADIENTDIRECT.LINE,
    this.points = points || [];
  }

  draw(painter) {
    if (this.points.length === 0) {
      return;
    }
    if (this.type === Polygon.TYPE.STROKE) {
      painter.strokeStyle = this.color;
      painter.lineWidth = this.lineWidth;
      if (this.lineDash.length > 0) {
        painter.setLineDash(this.lineDash);
      }
    } else {
      painter.fillStyle = this.color;
    }
    if (this.linearGradient.length > 0) {
      let minX = this.points[0].x, maxX = this.points[0].x,
        minY = this.points[0].y, maxY = this.points[0].y;
      for (let i = 0; i < this.points.length; i++) {
        if (minX > this.points[i].x) {
          minX = this.points[i].x;
        }
        if (maxX < this.points[i].x) {
          maxX = this.points[i].x;
        }
        if (minY > this.points[i].y) {
          minY = this.points[i].y;
        }
        if (maxY < this.points[i].y) {
          maxY = this.points[i].y;
        }
      }
      let lingrad = null;
      if (this.gradientDirect === Polygon.GRADIENTDIRECT.RADIAL) {
        const radius = Math.sqrt((maxY - minY) * (maxY - minY) + (maxX - minX) * (maxX - minX));
        lingrad = painter.createRadialGradient(
          (minX + maxX) / 2 + this.left,
          -(minY + maxY) / 2 + this.bottom,
          0,
          (minX + maxX) / 2 + this.left,
          -(minY + maxY) / 2 + this.bottom,
          radius / 2,
        );
      } else {
        lingrad = painter.createLinearGradient(
          this.left + minX,
          this.bottom - minY,
          this.left + maxX,
          this.bottom - maxY
        );
      }
      for (let i = 0; i < this.linearGradient.length; i++) {
        lingrad.addColorStop(this.linearGradient[i][0], this.linearGradient[i][1]);
      }
      if (this.type === Polygon.TYPE.STROKE) {
        painter.strokeStyle = lingrad;
      } else {
        painter.fillStyle = lingrad;
      }
    }
    // painter.translate(0, this.canvas.ratio * this.bottom);
    painter.beginPath();
    painter.moveTo(this.left + this.points[0].x, this.bottom - this.points[0].y);
    // 遍历所有的点绘制多边形
    for (let i = 1; i < this.points.length; i++) {
      painter.lineTo(this.left + this.points[i].x, this.bottom - this.points[i].y);
    }
    painter.closePath();
    if (this.type === Polygon.TYPE.STROKE) {
      painter.stroke();
    } else {
      painter.fill();
    }
  }

  containsPoint (point) {
    let crossings = 0;
    point = { x: point.x - this.left, y: point.y - this.bottom };
    for(let i = 0; i < this.points.length; i++) {
      const point1 = this.points[i];
      const point2 = i + 1 === this.points.length ? this.points[0] : this.points[i + 1];
      const slope = (point1.y - point2.y) / (point1.x - point2.x);
      const cond1 = point2.x <= point.x && point.x < point1.x;
      const cond2 = point1.x <= point.x && point.x < point2.x;
      const above = (point.y < slope * (point.x - point2.x) + point2.y);
      if ((cond1 || cond2) && above) crossings++;
    }
    console.log('crossings===>', crossings, crossings % 2 !== 0 && crossings !== 0)
    return crossings % 2 !== 0 && crossings !== 0;
  }
}
